import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:gd_assistant/globalConfig.dart';
import 'package:gd_assistant/main.dart';
import 'package:gd_assistant/page/public/publicView.dart';
import 'package:gd_assistant/util/dataUtil.dart';

/*
 * 网络请求管理类
 */
class DioManager {
  //写一个单例
  //在 Dart 里，带下划线开头的变量是私有变量
  static DioManager _instance;

  static DioManager getInstance() {
    if (_instance == null) {
      _instance = DioManager();
    }
    return _instance;
  }
  Dio dio = new Dio();
  DioManager() {
    //测试 https://webtest.zlycare.com
    //正式 https://webpro.zlycare.com
    dio.options.baseUrl = "https://webpro.zlycare.com";
    dio.options.connectTimeout = 5000; 
    dio.options.receiveTimeout = 3000;
    dio.interceptors.add(LogInterceptor(responseBody: GlobalConfig.isDebug)); //是否开启请求日志
  }

  //get请求
  get(String url, Map<String, dynamic> params) async {
    return await _requstHttp(url,'get', params);
  }

   //post请求
  post(String url, Map<String, dynamic> params) async {
    return await _requstHttp(url, "post", params);
  }

   _requstHttp(String url,
        [String method, Map<String, dynamic> params]) async {
        Response response;
         dio.options.headers = {
            "x-docchat-user-id" : dataUtil.getValue(dataUtil.assistantIdKey) != null ? dataUtil.getValue(dataUtil.assistantIdKey) : "",
            "x-docchat-session-token" : dataUtil.getValue(dataUtil.tokenKey) != null ? dataUtil.getValue(dataUtil.tokenKey) : "",
            "x-docchat-app-type" : "assistant"
        };
        try {
          if (method == 'get') {
            if (params != null && params.isNotEmpty) {
              response = await dio.get(url, queryParameters: params);
            } else {
              response = await dio.get(url);
            }
          } else if (method == 'post') {
            if (params != null && params.isNotEmpty) {
              response = await dio.post(url, data: params);
            } else {
              response = await dio.post(url);
            }
          }
      }on DioError catch(error) {
        // 请求错误处理
        Response errorResponse;
        if (error.response != null) {
          errorResponse = error.response;
        } else {
          errorResponse = new Response(statusCode: 666);
        }
        // 请求超时
        if (error.type == DioErrorType.connectTimeout) {
          errorResponse.statusCode = ResultCode.CONNECT_TIMEOUT;
        }
        // 一般服务器错误
        else if (error.type == DioErrorType.receiveTimeout) {
          errorResponse.statusCode = ResultCode.RECEIVE_TIMEOUT;
        }
    
        // debug模式才打印
        if (GlobalConfig.isDebug) {
          print('请求异常: ' + error.toString());
          print('请求异常url: ' + url);
          print('请求头: ' + dio.options.headers.toString());
          // print('method: ' + dio.options.method);
        }
        
        if (error.response != null && error.response.data != null && error.response.data != "" && error.response.data['code'] != null && error.response.data['code'] == 4002) {
          //退出登录
          dataUtil.removeAll();
          TostUtil.show("您的登录信息已失效，请重新登录");
          Navigator.of(dataUtil.context).pushAndRemoveUntil(MaterialPageRoute(builder: (context) {
            return LoginApp();
          },fullscreenDialog: true), (route) => false);
        }

         _error(error.message);
      }   
      // debug模式打印相关数据
      if (GlobalConfig.isDebug) {
        print('请求url: ' + url);
        print('请求头: ' + dio.options.headers.toString());
        if (params != null) {
          print('请求参数: ' + params.toString());
        }
        if (response != null) {
          print('返回参数: ' + response.toString());
        }
      }  
      String dataStr = json.encode(response != null ? response.data : {'code':'201'});
      Map<String, dynamic> dataMap = json.decode(dataStr);
      if (dataMap == null || (dataMap['code'] != null && dataMap['code'] != "200")) {
        if (dataMap['msg'] != null) {
          _error(dataMap['msg']);
        }else{
          _error("请求出现错误");
        }
      }else {
        return dataMap;
      }
    }

    //统一处理错误
    _error(String error) {
      TostUtil.show(error);
      return null;
    }
}

/*
 * dio网络请求失败的回调错误码 
 */
class ResultCode {
  //正常返回是1
  static const SUCCESS = 1;
  
  //异常返回是0
  static const ERROR = 1;
  
  /// When opening  url timeout, it occurs.
  static const CONNECT_TIMEOUT = -1;

  ///It occurs when receiving timeout.
  static const RECEIVE_TIMEOUT = -2;

  /// When the server response, but with a incorrect status, such as 404, 503...
  static const RESPONSE = -3;
  /// When the request is cancelled, dio will throw a error with this type.
  static const CANCEL = -4;

  /// read the DioError.error if it is not null.
  static const DEFAULT = -5;
}
